<!DOCTYPE html>
<!--
Take frames coming from various sources and render them to a canvas with
WebGLRenderingContext.texImage2D().
-->
<html>

<head>
  <title>texImage2D() test</title>
  <script src="webcodecs_common.js"></script>
  <script id="fragment-shader" type="glsl">
    uniform sampler2D tex;

    void main(void) {
      mediump vec2 coord = vec2(gl_FragCoord.x/640.0, 1.0 - (gl_FragCoord.y/480.0));
      mediump vec4 sample = texture2D(tex, coord);
      gl_FragColor = vec4(sample.r, sample.g, sample.b, 1.0);
    }
  </script>

  <script id="vertex-shader" type="glsl">
    attribute vec2 c;
    void main(void) {
      gl_Position=vec4(c, 0.0, 1.0);
    }
  </script>
  <script type="text/javascript">
    'use strict';
    async function main(arg) {
      const frames_to_draw = 5;
      let source_type = arg.source_type;
      let canvas = document.getElementById('display');
      let source =
        await createFrameSource(source_type, canvas.width, canvas.height);
      TEST.log('Starting test with arguments: ' + JSON.stringify(arg));
      if (!source) {
        TEST.skip('Unsupported source: ' + source_type);
        return;
      }

      var gl = canvas.getContext('webgl2');
      gl.viewport(0, 0, canvas.width, canvas.height);

      const vs = gl.createShader(gl.VERTEX_SHADER);
      gl.shaderSource(vs, document.getElementById('vertex-shader').innerText);
      gl.compileShader(vs);

      const fs = gl.createShader(gl.FRAGMENT_SHADER);
      gl.shaderSource(fs, document.getElementById('fragment-shader').innerText);
      gl.compileShader(fs);

      if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {
        TEST.log(gl.getShaderInfoLog(fs));
      }

      const program = gl.createProgram();
      gl.attachShader(program, vs);
      gl.attachShader(program, fs);
      gl.linkProgram(program);
      gl.useProgram(program);

      const vb = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, vb);
      gl.bufferData(
        gl.ARRAY_BUFFER, new Float32Array([-1, 1, -1, -1, 1, -1, 1, 1]),
        gl.STATIC_DRAW);

      const coordLoc = gl.getAttribLocation(program, 'c');
      gl.vertexAttribPointer(coordLoc, 2, gl.FLOAT, false, 0, 0);
      gl.enableVertexAttribArray(coordLoc);

      gl.clearColor(1, 1, 1, 1);
      gl.clear(gl.COLOR_BUFFER_BIT);

      const tex = gl.createTexture();
      gl.bindTexture(gl.TEXTURE_2D, tex);

      for (let i = 0; i < frames_to_draw; i++) {
        let frame = await source.getNextFrame();

        const format = gl.RGBA;
        gl.texImage2D(gl.TEXTURE_2D, 0, format, format, gl.UNSIGNED_BYTE, frame);
        gl.generateMipmap(gl.TEXTURE_2D);

        const texLoc = gl.getUniformLocation(program, 'tex');
        gl.uniform1i(texLoc, 0);

        gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);
        gl.finish();

        switch (source_type) {
          case 'camera': {
            if (arg.validate_camera_frames)
              checkFourColorsFrame(gl, canvas.width, canvas.height, 5);
            else
              TEST.log("Skip render result validation");
            break;
          }
          case 'offscreen':
          case 'arraybuffer':
          case 'capture': {
            checkFourColorsFrame(gl, canvas.width, canvas.height, 5);
            break;
          }
          case 'hw_decoder':
          case 'sw_decoder': {
            checkFourColorsFrame(gl, canvas.width, canvas.height, 15);
            break;
          }
          default:
            TEST.reportFailure("Unexpected frame source.");
        }
        frame.close();
        await waitForNextFrame();
      }
      source.close();
      TEST.log('Test completed');
    }
    addManualTestButton([{'source_type': 'offscreen'}]);
  </script>
</head>

<body>
  <div>
    <canvas id='display' width="640" height="480"></canvas>
  </div>
</body>

</html>